/*
 * TcpSession.cpp
 *
 *  Created on: 26/06/2011
 *      Author: george
 */


#include <sstream>
#include <iostream>
#include <fstream>
#include "tcpsession.h"
#include "defines.h"
#include <arpa/inet.h>
#include <netinet/in.h>
#include <cstdlib>

#include <sys/time.h>

#include "info.h"

using namespace std;


TcpSession::TcpSession(struct in_addr src, struct in_addr dst, u_int16_t src_port, u_int16_t dst_port, u_int8_t protocol) {

	Info::getInstance()->nmTcpSessions++;

	timeval time;
	std::ofstream packets;

	this->src_port = src_port;
	this->dst_port = dst_port;

	this->src = src;
	this->dst = dst;

	this->protocol = (u_int8_t)protocol;

//	Toda sessão iniciara com o status listen
	this->state = LISTEN;

//	Nome legivel da origem e destino da sessao icmp
	this->srcaddr = inet_ntoa(this->src);
	this->dstaddr = inet_ntoa(this->dst);

//	Para gerar o protocolo, porta de origem e destino como string
	stringstream protocol_name;



//	O o timestamp é utilizando para não termos dois arquivos com o mesmo nome para seçoes diferentes
	stringstream timestam_name;
	gettimeofday(&time, 0);
	timestam_name << time.tv_usec;
	stringstream src_port_name;
	stringstream dst_port_name;



	this->protocol_name << dec << this->protocol;
	this->src_port_name << dec << this->src_port;
	this->dst_port_name << dec << this->dst_port;


	this->filename = "tcp-" + this->srcaddr  + ":" + this->src_port_name.str()  + "-" + this->dstaddr + ':' + this->dst_port_name.str() + "-" + timestam_name.str() + ".xml";

	this->packets.open(this->filename.c_str(), ofstream::app);

	if ( !this->packets.is_open()){
		cout << "Erro ao abrir o arquivo " << this->filename << endl;

	}

	this->packets << "<tcpsession src='" + this->srcaddr + "' dst='" + this->dstaddr + "' src_port='" + this->src_port_name.str() + "' dst_port='" + this->dst_port_name.str() + "' protocol='" + this->protocol_name.str() + "' >" << endl;

}


bool TcpSession::add(tcp_hdr_t *tcp){

//	Verifica se o arquivo de saida esta aberto ou nao, se nao estiver o abre

	if (!this->packets.is_open()){
		this->packets.open(this->filename.c_str(), ofstream::app | ofstream::ate);

		if ( !this->packets.is_open() ){
			cout << "O arquivo " << this->filename << " não pode ser aberto" << endl;
			return false;
		}
	}

//	Ajusta o curso dentro do texto para sobrescrever o fim da tag icmpsession, desta forma sempre colocamops os pacotes detro do <icmpsession></icmpsession>
//	int end = this->packets.tellp();
//	this->packets.seekp(end - 13);

//	Escreve os dados do pacote capturado

    this->packets << "<tcp " <<
    	"src='"   << dec <<  (u_int16_t)ntohs(tcp->source)  <<
    	"' dst='" << dec <<  (u_int16_t)ntohs(tcp->dest)   <<
    	"' seq='" << dec << ntohl(tcp->seq)  <<
    	"' rec='" << dec <<	ntohl(tcp->ack_seq)  <<
    	"' hl='"  << dec << tcp->doff*4 <<
    	"' urg='" << tcp->urg  <<
    	"' ack='" << tcp->ack  <<
    	"' psh='" << tcp->psh  <<
    	"' rst='" << tcp->rst  <<
    	"' syn='" << tcp->syn  <<
    	"' fin='" << tcp->fin  <<
    	"' win='" << ntohs(tcp->window) <<
    	"' checksum='" << hex << ntohs(tcp->check)  <<
    	"' urgptr='" <<  tcp->urg_ptr << "' ></tcp>" << endl;

	this->packets.flush();
	return true;
}


void TcpSession::close(){
	this->packets << "</tcpsession>";
	this->packets.close();
}

